import select
import socket
import queue

import dbsql

#create a socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setblocking(False)
#set option reused
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR  , 1)

server_address= ('',9002)

try:
	server.bind(server_address)
except Exception as err:
	print(err)

server.listen(5)

#sockets from which we except to read
inputs = [server]

#sockets from which we expect to write
outputs = []

#Outgoing message queues (socket:Queue)
message_queues = {}

#A optional parameter for select is TIMEOUT
timeout = 20

mysql = dbsql.storeData()

while inputs:
	#print("waiting for next event")
	readable , writable , exceptional = select.select(inputs, outputs, inputs)

	# When timeout reached , select return three empty lists
	if not (readable or writable or exceptional) :
		print("Time out ! ")
		break;    
	for cur_sock in readable :
		if cur_sock is server:
			# A "readable" socket is ready to accept a connection
			connection, client_address = cur_sock.accept()
			print("    connection from ", client_address)
			connection.setblocking(0)
			inputs.append(connection)
			message_queues[connection] = queue.Queue()
		else:
			try:
				data = cur_sock.recv(1024)
			except Exception as err:
				print(err)
				data = 0

			if data :
				mysql.save(data)

				#print(" received " , data , "from ",cur_sock.getpeername())
				#message_queues[cur_sock].put(data)
				# Add output channel for response
				if cur_sock not in outputs:
					outputs.append(cur_sock)
			else:
				#Interpret empty result as closed connection
				#print("  closing", client_address)
				if cur_sock in outputs :
					outputs.remove(cur_sock)
				inputs.remove(cur_sock)
				cur_sock.close()
				#remove message queue 
				del message_queues[cur_sock]
	for cur_sock in writable:
		try:
			next_msg = message_queues[cur_sock].get_nowait()
		except queue.Empty:
			#print(" " , cur_sock.getpeername() , 'queue empty')
			outputs.remove(cur_sock)
		else:
			print(" sending " , next_msg , " to ", cur_sock.getpeername())
			cur_sock.send(next_msg)

	for cur_sock in exceptional:
		print(" exception condition on ", cur_sock.getpeername())
		#stop listening for input on the connection
		inputs.remove(cur_sock)
		if cur_sock in outputs:
			outputs.remove(cur_sock)
		cur_sock.close()
		#Remove message queue
		del message_queues[cur_sock]
